#include "Renderer.h"

Renderer::Renderer(): m_Device(0),
	    m_Fvf(D3DFVF_XYZ | D3DFVF_DIFFUSE),
		m_VertSize(sizeof(float3) + sizeof(D3DCOLOR)),
		m_vertexBuffer(0)
{
}

Renderer::Renderer(D3DDevice device): 
		m_Device(0), m_Fvf(D3DFVF_XYZ | D3DFVF_DIFFUSE),
		m_VertSize(sizeof(float3) + sizeof(D3DCOLOR)),
		m_vertexBuffer(0)
{
	setDevice(device);
}

Renderer::~Renderer()
{
	destroy();
}

void Renderer::destroy()
{
	m_Device = NULL;
	SAFE_RELEASE(m_vertexBuffer);
}


void Renderer::setDevice(D3DDevice device)
{
	if(!device) return;
	m_Device = device;
}

void Renderer::setup(const poly::Polygon &poly, float3 color)
{
	if(!m_Device) return;

	if(poly.size() <= 0) return;

	//convert colors to DX readable colors
	D3DCOLOR c = D3DCOLOR_ARGB(255, (uint32)(color.x*255), 
									(uint32)(color.y*255), 
									(uint32)(color.z*255));


	SAFE_RELEASE(m_vertexBuffer);

	uint32 VSize = m_VertSize * poly.size();
	
	m_Device->CreateVertexBuffer(
		      VSize,
			  0, // usage
			  m_Fvf,
			  D3DPOOL_MANAGED,
			  &m_vertexBuffer,
			  0 );

	uint8 *data = 0;
	m_vertexBuffer->Lock( 0, 0, (void**)&data, 0 );
	{
		for( uint32 i = 0; i < poly.size(); i++ )
		{
			memcpy( data, &(poly[i]), sizeof(float3) );
			data += sizeof(float3);
			memcpy( data, &(c),   sizeof(D3DCOLOR) );
			data += sizeof(D3DCOLOR);
		}
	}
	m_vertexBuffer->Unlock();

}

void Renderer::setup(const poly::Polygon &poly, const poly::Polygon &color)
{
	if(!m_Device) return;

	if(poly.size() <= 0 || color.size() <= 0 ||
	   poly.size() != color.size())
		return;

	std::vector<D3DCOLOR>	Color;

	//convert colors to DX readable colors
	for(uint32 i = 0; i<color.size(); i++)
	{
		D3DCOLOR c = D3DCOLOR_ARGB(255, (uint32)(color[i].x*255), 
										(uint32)(color[i].y*255), 
										(uint32)(color[i].z*255));
		Color.push_back(c);
	}


	SAFE_RELEASE(m_vertexBuffer);

	uint32 VSize = m_VertSize * poly.size();
	
	m_Device->CreateVertexBuffer(
		      VSize,
			  0, // usage
			  m_Fvf,
			  D3DPOOL_MANAGED,
			  &m_vertexBuffer,
			  0 );

	uint8 *data = 0;
	m_vertexBuffer->Lock( 0, 0, (void**)&data, 0 );
	
		for( uint32 i = 0; i < poly.size(); i++ )
		{
			memcpy( data, &(poly[i]), sizeof(float3) );
			data += sizeof(float3);
			memcpy( data, &(Color[i]),   sizeof(D3DCOLOR) );
			data += sizeof(D3DCOLOR);
		}

	m_vertexBuffer->Unlock();
}

void Renderer::render(int PrimitiveType, uint32 PrimitiveCount )
{
	if(!m_vertexBuffer || !m_Device) return;
	D3DPRIMITIVETYPE pt = (D3DPRIMITIVETYPE)PrimitiveType;

	DWORD lightState;	

	m_Device->SetStreamSource( 0, m_vertexBuffer, 0, m_VertSize );
	m_Device->SetFVF(m_Fvf);

	m_Device->GetRenderState( D3DRS_LIGHTING, &lightState);

	m_Device->SetRenderState( D3DRS_LIGHTING, FALSE );
	m_Device->DrawPrimitive(pt, 0, PrimitiveCount);

	m_Device->SetRenderState( D3DRS_LIGHTING, lightState );
}

